package com.sh.datasync.util;

import com.sh.datasync.model.PlmFileData;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.File;
import java.util.*;

public class PlmFileScanner {
    public static List<PlmFileData> scanDirectory(String dirPath, String fileType) {
        List<PlmFileData> result = new ArrayList<>();
        File dir = new File(dirPath);
        File[] files = dir.listFiles((d, name) -> name.toLowerCase().endsWith(".xml"));
        if (files == null) return result;
        for (File file : files) {
            try {
                System.out.println("扫描到文件：" + file.getAbsolutePath());
                List<PlmFileData> dataList = parseXml(file, fileType);
                if (dataList != null) result.addAll(dataList);
            } catch (Exception e) {
                System.out.println("扫描文件失败: " + file.getName() + " - " + e.getMessage());
                e.printStackTrace();
            }
        }
        return result;
    }

    public static List<PlmFileData> parseXml(File file, String fileType) throws Exception {
        List<PlmFileData> dataList = new ArrayList<>();
        
        // 验证文件是否为空或太小
        if (!file.exists() || file.length() < 10) {
            throw new Exception("XML文件不存在或文件太小: " + file.getName());
        }
        
        // 检查文件是否被其他程序占用
        if (!file.canRead()) {
            throw new Exception("无法读取XML文件(可能被占用): " + file.getName());
        }
        
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        // 增加安全配置
        try {
            dbFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
            dbFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
            dbFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
        } catch (Exception e) {
            // 如果不支持这些安全特性，继续执行
        }
        
        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
        
        // 设置错误处理器
        dBuilder.setErrorHandler(new org.xml.sax.ErrorHandler() {
            public void warning(org.xml.sax.SAXParseException e) throws org.xml.sax.SAXException {
                System.out.println("XML警告 [" + file.getName() + "]: " + e.getMessage());
            }
            public void error(org.xml.sax.SAXParseException e) throws org.xml.sax.SAXException {
                throw e;
            }
            public void fatalError(org.xml.sax.SAXParseException e) throws org.xml.sax.SAXException {
                throw e;
            }
        });
        
        Document doc;
        try {
            doc = dBuilder.parse(file);
            doc.getDocumentElement().normalize();
            
            // 验证根元素
            Element root = doc.getDocumentElement();
            if (root == null) {
                throw new Exception("XML文件没有根元素: " + file.getName());
            }
            
        } catch (org.xml.sax.SAXParseException e) {
            throw new Exception("XML格式错误 [" + file.getName() + "] 行:" + e.getLineNumber() + " 列:" + e.getColumnNumber() + " - " + e.getMessage());
        } catch (Exception e) {
            throw new Exception("解析XML文件失败: " + file.getName() + " - " + e.getMessage());
        }

        NodeList partList = doc.getElementsByTagName("Part");
        if (partList.getLength() == 0) {
            System.out.println("警告: XML文件中没有找到Part元素: " + file.getName());
            return dataList; // 返回空列表而不是抛出异常
        }
        
        for (int i = 0; i < partList.getLength(); i++) {
            try {
                Element partElem = (Element) partList.item(i);
                NodeList propertiesNodes = partElem.getElementsByTagName("Properties");
                if (propertiesNodes.getLength() == 0) {
                    System.out.println("警告: Part元素中没有Properties节点，跳过该Part: " + file.getName());
                    continue;
                }
                
                Element propsElem = (Element) propertiesNodes.item(0);
                NodeList partProperties = propsElem.getElementsByTagName("PartProperty");
                
                Map<String, String> map = new HashMap<>();
                for (int j = 0; j < partProperties.getLength(); j++) {
                    Element prop = (Element) partProperties.item(j);
                    String idx = prop.getAttribute("PropertyIndex");
                    if (idx != null && !idx.trim().isEmpty()) {
                        map.put(idx, prop.getTextContent());
                    }
                }
                
                PlmFileData data = new PlmFileData();
                data.setFileName(file.getName());
                data.setFileType(fileType);
                data.setErpCode(map.get("1"));
                data.setPartNumber(map.get("2"));
                data.setCategory(map.get("3"));
                data.setProductGroup(map.get("4"));
                data.setSubProductGroup(map.get("5"));
                data.setPartName(map.get("6"));
                data.setTypeNumber(map.get("7"));
                data.setTechParam(map.get("8"));
                data.setDescription(map.get("9"));
                data.setScanTime(new Date(file.lastModified()));
                dataList.add(data);
                
            } catch (Exception e) {
                System.out.println("警告: 处理Part元素时出错 [" + file.getName() + "], 跳过该Part: " + e.getMessage());
                continue;
            }
        }
        return dataList;
    }

    // 修改：写入所有Part数据到日志
    public static void scanAndWriteLog(File xmlFile, String fileType, String logDir) throws Exception {
        List<PlmFileData> dataList = parseXml(xmlFile, fileType);
        String logFileName = fileType + "_" + xmlFile.getName() + ".log";
        File logFile = new File(logDir, logFileName);
        logFile.getParentFile().mkdirs();
        try (java.io.PrintWriter writer = new java.io.PrintWriter(logFile, "UTF-8")) {
            for (PlmFileData data : dataList) {
                writer.println(
                        String.join("|",
                                data.getFileName(),
                                data.getFileType(),
                                data.getErpCode() == null ? "" : data.getErpCode(),
                                data.getPartNumber() == null ? "" : data.getPartNumber(),
                                data.getCategory() == null ? "" : data.getCategory(),
                                data.getProductGroup() == null ? "" : data.getProductGroup(),
                                data.getSubProductGroup() == null ? "" : data.getSubProductGroup(),
                                data.getPartName() == null ? "" : data.getPartName(),
                                data.getTypeNumber() == null ? "" : data.getTypeNumber(),
                                data.getTechParam() == null ? "" : data.getTechParam(),
                                data.getDescription() == null ? "" : data.getDescription(),
                                data.getScanTime() == null ? "" : data.getScanTime().toString()
                        )
                );
            }
        }
    }
}